﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml;
using iTextSharp.text;
using iTextSharp.text.pdf;

namespace DataCreateUtility
{
    class DataCreation
    {
        private String Filepath;

        private DateTime Time_Stamp = DateTime.Now;
        private Random Rand = new Random(Properties.Settings.Default.Random_Seed);
        private long Tota_Files=Properties.Settings.Default.Total_No_Files;
        private String XML_File_path = Properties.Settings.Default.XMLPath;
        private String Results_File_path = Properties.Settings.Default.ResultFilePath;
        private int Min_Size_Range=Properties.Settings.Default.Min_File_Size;
        private int Max_Size_Range = Properties.Settings.Default.Max_File_Size;
        private String File_Name = Properties.Settings.Default.File_Names;
        private String File_Ext = Properties.Settings.Default.File_Ext;
        private String XML_Files = Properties.Settings.Default.XML_File_Names;
        
        /// <summary>
        /// Method will write/flush the data to a file as per their extensions
        /// </summary>
        /// <param name="Data">Data which needs to be written in a file</param>
        private void Write_File(StringBuilder Data,String File_Ext_Now)
        {
            if (File_Ext_Now.ToUpper().Contains("PDF"))
            {
                try
                {
                    var PDF_Doc = new Document();

                    using (PdfWriter.GetInstance(PDF_Doc, new FileStream(Filepath, FileMode.Create)))
                    {
                        PDF_Doc.Open();
                        PDF_Doc.Add(new Paragraph(Data.ToString()));
                        PDF_Doc.Close();
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
            }
            else if (File_Ext_Now.ToUpper().Contains("DOC"))
            {
                Doc_write Word_Doc = new Doc_write();
                Word_Doc.Doc_generate(Filepath, Data.ToString());
            }
            else
            {
                using (FileStream File_Writer = File.Create(Filepath))
                {
                    byte[] info = new UTF8Encoding(true).GetBytes(Data.ToString());
                    File_Writer.Write(info, 0, info.Length);
                }
            }
        }

        /// <summary>
        /// Method to Generate the Garbage Data for populating the Document.
        /// </summary>
        /// <param name="Low">Least Ascii Value to be used</param>
        /// <param name="High">Highest Ascii Value to be used</param>
        /// <param name="length">Length of characters to be generated</param>
        /// <returns></returns>
        private StringBuilder Generate_Data(int Low, int High, Int32 length,StringBuilder XML_Data)
        {

            StringBuilder Result = new StringBuilder(length);
            String[] XML_bits = null;

            if (XML_Data.Length != 0)
            {
                XML_bits=XML_Data.ToString().Split(';');
            }

            for (Int64 i = 0; i < length; i++)
            {
                Result.Append((char)Rand.Next(Low, 90));
                
                if (i % Rand.Next(5,15) == 0)
                {
                    Result.Append(" ");
                }

                Result.Append((char)Rand.Next(97, High));

                if (i % Rand.Next(10, 20) == 0 && XML_Data.Length != 0)
                {
                    Result.Append(" "+XML_bits[Rand.Next(0, XML_bits.Length)]+" ");
                }
            }
            
            return Result;
        }

        /// <summary>
        /// Method will load the XML and parses the Elements present in XML file.
        /// </summary>
        /// <param name="XML_Data"></param>
        private String Parse_XML()
        {
            StringBuilder Result = new StringBuilder();
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(Filepath);

                //Checking for the Declaration Element in XML (First or Second Node)
                if (doc.FirstChild.NodeType == XmlNodeType.XmlDeclaration)
                {
                    Result = ParseMyXmlFile(doc.ChildNodes[1]);
                }
                else
                {
                    Result = ParseMyXmlFile(doc.FirstChild);
                }
            }
            catch (Exception Exc_XML)
            {
                Console.WriteLine(Exc_XML.Message);
            }

            return Result.ToString();
        }

        /// <summary>
        ///  Method will parse the XML child nodes from the root element.
        /// </summary>
        /// <param name="xmlNode"> The Root node from which child Nodes should be parsed.</param>
        private StringBuilder ParseMyXmlFile(XmlNode xmlNode)
        {
            StringBuilder Result = new StringBuilder();

            foreach (XmlNode node in xmlNode)
            {
                foreach (XmlNode child in node.ChildNodes)
                {
                    Result.Append(child.InnerText+";");
                }
            }
            return Result;
        }

        /// <summary>
        /// Complete Method for File Generation.
        /// </summary>
        /// <param name="Total_no_Files"></param>
        public void File_Generation_Process()
        {
            int File_Ext_Index = File_Ext.Split(';').Length;
            StringBuilder Complete_XML_Data = new StringBuilder();
            StringBuilder New_File_Ext = new StringBuilder();


            //Generic block for reading data from all XML Files listed.
            if (XML_Files.Length != 0 && XML_File_path.Length != 0)
            {
                for (int j = 0; j < XML_Files.Split(';').Length; j++)
                {
                    Filepath = XML_File_path + XML_Files.Split(';')[j] + ".xml";
                    Complete_XML_Data.Append(Parse_XML());
                }
                Complete_XML_Data = new StringBuilder();
            }


                //Generating Random Data and Writing data to the Files.
                for (long i = 0; i < Tota_Files; i++)
                {
                    New_File_Ext = new StringBuilder(File_Ext.Split(';')[Rand.Next(0, File_Ext_Index)]);
                    Console.WriteLine("File Creation in Progress..... File No " + i);
                    Filepath = Results_File_path + File_Name + "_" + Time_Stamp.ToString("yyyyMMdd") + "_" + Time_Stamp.ToString("HHmmss") + "_" + i + "." + New_File_Ext.ToString();
                    Write_File(Generate_Data(65, 122, Rand.Next(Min_Size_Range, Max_Size_Range), Complete_XML_Data), New_File_Ext.ToString());
                    Console.WriteLine("File No " + i + " Created Successfylly.");
                }

        }

        /// <summary>
        /// Method will read the Files from the Mentioned FilePath
        /// </summary>
        /// <returns></returns>
        private StringBuilder Read_File()
        {
            StringBuilder Result = new StringBuilder();


            //Block will read the Data from the 
            using (FileStream File_Reader = File.OpenRead(Filepath))
            {
                byte[] b = new byte[1024];
                UTF8Encoding temp = new UTF8Encoding(true);
                while (File_Reader.Read(b, 0, b.Length) > 0)
                {
                    Result.Append(temp.GetString(b));
                }
            }

            return Result;
        }
    }
}
